import Checkbox from '../Checkbox/Checkbox'; // eslint-disable-line
// import Radio from '../Radio/Radio'; // eslint-disable-line
import { mixins } from './utils';
import { Radio } from 'view-design'; // eslint-disable-line

/* eslint-disable no-underscore-dangle */
export default {
  name: 'TreeTable__body',
  mixins: [mixins],
  components: { Radio },
  data() {
    return {
      radioSelectedIndex: -1
    };
  },
  computed: {
    table() {
      return this.$parent;
    },
  },
  methods: {

    toggleStatus(type, row, rowIndex, value) {
      this.validateType(type, ['Expanded', 'Checked', 'Hide', 'Fold'], 'toggleStatus', false);
      const target = this.table.bodyData[rowIndex];
      // 更新折叠状态
      if (type === 'Fold') {
        this.table.foldStatus[target[this.table.idProp]].status = typeof value === 'undefined' ? !row[`_is${type}`] : value;
      }
      this.table.bodyData.splice(rowIndex, 1, {
        ...target,
        [`_is${type}`]: typeof value === 'undefined' ? !row[`_is${type}`] : value,
      });
    },
    handleEvent($event, type, data, others) {
      const certainType = this.validateType(type, ['cell', 'row', 'checkbox', 'icon', 'radio', 'edit'], 'handleEvent');
      const eventType = $event ? $event.type : '';
      const { row, rowIndex, column, columnIndex } = data;
      const latestData = this.table.bodyData;
      // Checkbox
      if (certainType.checkbox) {
        const { isChecked } = others;
        this.toggleStatus('Checked', row, rowIndex, isChecked);

        this.table.checkedData.push(row);
        if (row._childrenLen > 0) {
          const childrenIndex = this.table.getChildrenIndex(row._level, rowIndex, false);
          for (let i = 0; i < childrenIndex.length; i++) {
            this.toggleStatus('Checked', latestData[childrenIndex[i]], childrenIndex[i], isChecked);
          }
        }
        return this.table.$emit('checkbox-click', latestData[rowIndex], column, columnIndex, $event);
      }
      // Radio
      if (certainType.radio) {
        this.radioSelectedIndex = rowIndex;
        return this.table.$emit('radio-click', { row, rowIndex, column, columnIndex, $event });
      }
      // Tree's icon
      if (certainType.icon) {
        $event.stopPropagation();
        this.toggleStatus('Fold', row, rowIndex);
        const childrenIndex = this.table.getChildrenIndex(row._level, rowIndex);
        for (let i = 0; i < childrenIndex.length; i++) {
          this.toggleStatus('Hide', latestData[childrenIndex[i]], childrenIndex[i]);
        }
        var isExpanded = $event.target.className.indexOf('fa-plus-square-o') > 0;
        return this.table.$emit('tree-icon-click', latestData[rowIndex], column, columnIndex, $event, isExpanded);
      }
      if (certainType.cell && eventType === 'click') {
        // 点击扩展单元格
        if (this.isExpandCell(this.table, columnIndex)) {
          this.toggleStatus('Expanded', row, rowIndex);
          return this.table.$emit('expand-cell-click', latestData[rowIndex], column, columnIndex, $event);
        }
      }
      // 行：Hover
      if (certainType.row && (eventType === 'mouseenter' || eventType === 'mouseleave')) {
        const { hover } = others;
        if (hover && $event.currentTarget.className.indexOf(`${this.prefixCls}--row-hover`) == -1) {
          $event.currentTarget.className = `${this.prefixCls}--row-hover ` + $event.currentTarget.className;
        } else {
          $event.currentTarget.className = $event.currentTarget.className.replace(`${this.prefixCls}--row-hover `, "");
        }
      }
      if (certainType.row && others && others.clickRow) {
        this.radioSelectedIndex = rowIndex;
        return this.table.$emit('radio-click', { row, rowIndex, column, columnIndex, $event });
      }
      if (certainType.cell) {
        return this.table.$emit(`${type}-${eventType}`, latestData[rowIndex], rowIndex, column, columnIndex, $event);
      }
      return this.table.$emit(`${type}-${eventType}`, latestData[rowIndex], rowIndex, $event);
    },
  },
  render() {
    // key
    // function getKey(row, rowIndex) {
    //   const rowKey = this.table.rowKey;
    //   if (rowKey) {
    //     return rowKey.call(null, row, rowIndex);
    //   }
    //   return rowIndex;
    // }

    // style
    function getStyle(type, row, rowIndex, column, columnIndex) {
      const certainType = this.validateType(type, ['cell', 'row'], 'getStyle');
      const style = this.table[`${type}Style`];
      if (typeof style === 'function') {
        if (certainType.row) {
          return style.call(null, row, rowIndex);
        }
        if (certainType.cell) {
          return style.call(null, row, rowIndex, column, columnIndex);
        }
      }
      return style;
    }

    // className
    function getClassName(type, row, rowIndex, column, columnIndex) {
      const certainType = this.validateType(type, ['cell', 'row', 'inner'], 'getClassName');
      const classList = [];
      if (certainType.row || certainType.cell) {
        const className = this.table[`${type}ClassName`];
        if (typeof className === 'string') {
          classList.push(className);
        } else if (typeof className === 'function') {
          if (certainType.row) {
            classList.push(className.call(null, row, rowIndex) || '');
          }
          if (certainType.cell) {
            classList.push(className.call(null, row, rowIndex, column, columnIndex) || '');
          }
        }
        if (certainType.row) {
          classList.push(`${this.prefixCls}__body-row`);
          if (this.table.stripe && rowIndex % 2 !== 0) {
            classList.push(`${this.prefixCls}--stripe-row`);
          }
        }
        if (certainType.cell) {
          classList.push(`${this.prefixCls}__body-cell`);
          if (this.table.border) {
            classList.push(`${this.prefixCls}--border-cell`);
          }
          const align = column.align;
          if (['center', 'right'].indexOf(align) > -1) {
            classList.push(`${this.prefixCls}--${align}-cell`);
          }
        }
      }
      if (certainType.inner) {
        classList.push(`${this.prefixCls}__cell-inner`);
        if (this.isExpandCell(this.table, columnIndex)) {
          classList.push(`${this.prefixCls}--expand-inner`);
          if (row._isExpanded) {
            classList.push(`${this.prefixCls}--expanded-inner`);
          }
        }
        if (column && column.className) {
          column.className.forEach((item,idx) => classList.push(item));
        }
      }
      return classList.join(' ');
    }

    function renderTitle(row, rowIndex, column, columnIndex) {
      return row[column.key];
    }

    // 渲染自定义行
    function renderCustomRow(row, rowIndex, tmpData) {
      return this.table.$scopedSlots['$createdata']({row, rowIndex, tmpData});
    }

    // 根据type渲染单元格Cell
    function renderCell(row, rowIndex, column, columnIndex) {
      // ExpandType
      if (this.isExpandCell(this.table, columnIndex)) {
        return <i class='fa fa-angle-right'></i>;
      }
      // SelectionType's Checkbox
      if (this.isSelectionCell(this.table, columnIndex)) {
        let res = null;
        if (this.table.selectType === 'checkbox') {
          let allCheck;
          let childrenIndex;
          const hasChildren = row._childrenLen > 0;
          let allDisabled = false;
          if (hasChildren) {
            childrenIndex = this.table.getChildrenIndex(row._level, rowIndex, false);
            allCheck = true;
            for (let i = 0; i < childrenIndex.length; i++) {
              if (!this.table.bodyData[childrenIndex[i]]._isChecked) {
                allCheck = false;
                break;
              }
            }
            allDisabled = true;
            for (let i = 0; i < childrenIndex.length; i++) {
              if (!this.table.bodyData[childrenIndex[i]]._isDisabled) {
                allDisabled = false;
                break;
              }
            }
          } else {
            allDisabled = row._isDisabled;
            allCheck = row._isChecked;
          }
          let indeterminate = false;
          if (hasChildren && !allCheck) {
            for (let i = 0; i < childrenIndex.length; i++) {
              if (this.table.bodyData[childrenIndex[i]]._isChecked) {
                indeterminate = true;
                break;
              }
            }
          }
          res = <Checkbox
            indeterminate={ indeterminate }
            value={ allCheck }
            disabled = { allDisabled }
            on-on-change={ isChecked => this.handleEvent(null, 'checkbox', { row, rowIndex, column, columnIndex }, { isChecked }) }>
          </Checkbox>;
        } else {
          res = <Radio value={this.radioSelectedIndex === rowIndex} on-on-change={ () => this.handleEvent(null, 'radio', { row, rowIndex, column, columnIndex }) }></Radio>;
        }
        return res;
      }
      // Tree's firstProp
      if (this.table.treeType && this.table.firstProp === column.key) {
        return <span
          class={ `${this.prefixCls}--level-${row._level}-cell` }
          style={{
            marginLeft: `${(row._level - 1) * 24}px`,
            paddingLeft: (row[this.table.forceExpandIconProp] != undefined && !row[this.table.forceExpandIconProp]) || row._childrenLen > 0 ? '' : '20px',
          }}>
            { (!this.table.treeLoading[row[this.table.idProp]] && (row._childrenLen > 0 || (row[this.table.forceExpandIconProp] != undefined && !row[this.table.forceExpandIconProp]))) &&
              <i
                class={ `${this.prefixCls}--tree-icon fa fa-${row._isFold ? 'plus' : 'minus'}-square-o`}
                on-click={ $event => this.handleEvent($event, 'icon', { row, rowIndex, column, columnIndex }, { isFold: row._isFold }) }></i>
            }
            { (this.table.treeLoading[row[this.table.idProp]]) &&
              <i class={ `${this.prefixCls}--tree-icon fa fa-spinner fa-spin fa-fw`}></i>
            }
            <span>
              {
                column.type === 'template' ? (this.table.$scopedSlots[column.template]
                ? this.table.$scopedSlots[column.template]({ row, rowIndex, column, columnIndex })
                : row[column.key]) : row[column.key]
              }
            </span>
        </span>;
      }
      // TreeType children's index
      if (this.table.showIndex && this.table.treeType && column.key === '_normalIndex' && row._level > 1) {
        return '';
      }
      if (column.type === undefined || column.type === 'custom') {
        return <span>{row[column.key]}</span>;
      } else if (column.type === 'template') {
        return this.table.$scopedSlots[column.template]
        ? this.table.$scopedSlots[column.template]({ row, rowIndex, column, columnIndex })
        : '';
      }
      return '';
    }

    var $table = this.table;
    var $idProp = this.table.idProp;
    // Template
    return (
      <table cellspacing="0" cellpadding="0" border="0" class={ `${this.prefixCls}__body` }>
        <colgroup>
          { this.table.tableColumns.map(column =>
            <col width={ column.computedWidth || column.minWidth || column.width }></col>)
          }
        </colgroup>
        <tbody>
          <tr><td colspan={this.table.tableColumns.length}><div class={ `${this.prefixCls}__body-tmpdata` }>{this.table.$scopedSlots['$createdata'] ? renderCustomRow.call(this, {}, -1, $table.tmpData['$firstdata']) : ''}</div></td></tr>
          { this.table.bodyData.length > 0
            ? this.table.bodyData.map((row, rowIndex) =>
              [
                <tr
                  v-show={ !row._isHide }
                  key={ `table_row_${rowIndex}` }
                  style={ getStyle.call(this, 'row', row, rowIndex) }
                  class={ getClassName.call(this, 'row', row, rowIndex) }
                  on-click={ $event => this.handleEvent($event, 'row', { row, rowIndex }, { clickRow: true }) }
                  on-dblclick={ $event => this.handleEvent($event, 'row', { row, rowIndex }) }
                  on-contextmenu={ $event => this.handleEvent($event, 'row', { row, rowIndex }) }
                  on-mouseenter={ $event => this.handleEvent($event, 'row', { row, rowIndex }, { hover: true }) }
                  on-mouseleave={ $event => this.handleEvent($event, 'row', { row, rowIndex }, { hover: false }) }>
                  { this.table.tableColumns.map((column, columnIndex) =>
                      <td
                        style={ getStyle.call(this, 'cell', row, rowIndex, column, columnIndex) }
                        class={ getClassName.call(this, 'cell', row, rowIndex, column, columnIndex) }
                        on-click={ $event => this.handleEvent($event, 'cell', { row, rowIndex, column, columnIndex }) }
                        on-dblclick={ $event => this.handleEvent($event, 'cell', { row, rowIndex, column, columnIndex }) }
                        on-contextmenu={ $event => this.handleEvent($event, 'cell', { row, rowIndex, column, columnIndex }) }
                        on-mouseenter={ $event => this.handleEvent($event, 'cell', { row, rowIndex, column, columnIndex }) }
                        on-mouseleave={ $event => this.handleEvent($event, 'cell', { row, rowIndex, column, columnIndex }) }>
                        <div title={ renderTitle.call(this, row, rowIndex, column, columnIndex)} class={ getClassName.call(this, 'inner', row, rowIndex, column, columnIndex) }>
                          { renderCell.call(this, row, rowIndex, column, columnIndex) }
                        </div>
                      </td>)
                  }
                </tr>,
                this.table.expandType && row._isExpanded &&
                <tr
                  key={ rowIndex }
                  class={ `${this.prefixCls}__body-row ${this.prefixCls}--expand-row` }>
                  <td
                    class={ `${this.prefixCls}--expand-content` }
                    colspan={ this.table.tableColumns.length }>
                    { this.table.$scopedSlots.$expand
                      ? this.table.$scopedSlots.$expand({ row, rowIndex })
                      : ''
                    }
                   </td>
                </tr>,
                <tr><td colspan="999"><div class={ `${this.prefixCls}__body-tmpdata` }>{this.table.$scopedSlots['$createdata'] ? renderCustomRow.call(this, row, rowIndex, $table.tmpData[row[$idProp]]) : ''}</div></td></tr>
              ])
            : <tr
                class={ `${this.prefixCls}--empty-row` }>
                <td
                  class={ `${this.prefixCls}__body-cell ${this.prefixCls}--empty-content` }
                  colspan={ this.table.tableColumns.length }>
                  { this.table.emptyText }
                </td>
              </tr>
          }
        </tbody>
      </table>
    );
  },
};
